package de.dhbw.ka.tit09.picsim.model;

import java.util.LinkedList;

import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.WritableList;

import de.dhbw.ka.tit09.picsim.RealmProvider;

/**
 * Model of the general purpose registers which are represented in the GUI.
 * 
 * @author Andreas Bender
 * 
 */
public class GPRegisters extends WritableList {
	private volatile boolean run;
	private int buffer;

	/**
	 * Constructor.
	 */
	public GPRegisters() {
		super(Realm.getDefault(), new LinkedList<int[]>(), Integer.class);
	}

	/**
	 * Initializes the registers. Sets all values to zero.
	 */
	public void initGPRegisters() {
		run = false;

		RealmProvider.getUIRealm().exec(new Runnable() {
			public void run() {
				clear();
				run = true;
			}
		});

		while (!run) {
		}

		for (int i = 0; i < 6; i++) {
			add(new int[6]);
		}
	}

	/**
	 * Sets the value of the register at the specified address.
	 * 
	 * @param address the register address
	 * @param value the new register value
	 */
	public void setGPRAtAddress(int address, final int value) {
		final int index = address - 0xC;

		run = false;

		RealmProvider.getUIRealm().exec(new Runnable() {
			public void run() {
				final int[] tRow = (int[]) get(index / 6);
				tRow[index % 6] = value;
				set(index / 6, tRow);
				run = true;
			}
		});

		while (!run) {
		}
	}

	/**
	 * Returns the value of the register at the given address.
	 * 
	 * @param address the register address
	 * @return the register value
	 */
	public int getGPRAtAddress(int address) {
		final int index = address - 0xC;

		run = false;

		RealmProvider.getUIRealm().exec(new Runnable() {
			public void run() {
				buffer = ((int[]) get(index / 6))[index % 6];
				run = true;
			}
		});

		while (!run) {
		}

		return buffer;
	}
}
